﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using LmgCMS.Model;
using Microsoft.Extensions.Logging;
using Qiniu.Util;
using Quartz;

namespace LmgCMS.Service
{
    ///<summary>
    ///系统定时任务管理
    ///</summary>
    public interface IOpenJobService : IRepository<OpenJob>
    {
        /// <summary>
        ///启动所有状态为正在运行的任务
        ///<para>通常应用在系统加载的时候</para>
        /// </summary>
        void StartAll();
        /// <summary>
        /// 返回系统的job接口
        /// </summary>
        /// <returns></returns>
        List<string> QueryLocalHandlers();
        /// <summary>
        /// 改变任务状态
        /// </summary>
        /// <param name="jobId"></param>
        void ChangeJobStatus(ChangeJobStatusReq req);
        /// <summary>
        /// 记录任务运行结果
        /// </summary>
        /// <param name="jobId"></param>
        void RecordRun(string jobId);
    }
    ///<summary>
    ///系统定时任务管理
    ///</summary>
    public partial class OpenJobService : BaseRepository<OpenJob>, IOpenJobService
    {
        private IScheduler _scheduler;
        private ILogger<OpenJobService> _logger;
        private ILoginInfo _auth;
        private ISysLogService _sysLog;
        public OpenJobService(IScheduler scheduler,ILogger<OpenJobService> logger, ILoginInfo auth, ISysLogService sysLog)
        {
            _scheduler = scheduler;
            _logger = logger;
            _auth = auth;
            _sysLog = sysLog;
        }
        public void StartAll()
        {
            var jobs = base.FindAll(u => u.Status == (int)JobStatus.Running);
            foreach (var job in jobs)
            {
                job.Start(_scheduler);
            }
        }

        #region 定时任务运行相关操作
        /// <summary>
        /// 返回系统的job接口
        /// </summary>
        /// <returns></returns>
        public List<string> QueryLocalHandlers()
        {
            var types = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces()
                    .Contains(typeof(IJob))))
                .ToArray();
            return types.Select(u => u.FullName).ToList();
        }
        /// <summary>
        /// 改变任务状态
        /// </summary>
        /// <param name="req"></param>
        /// <exception cref="Exception"></exception>
        public void ChangeJobStatus(ChangeJobStatusReq req)
        {
            var job = Find(u => u.ID == req.Id);
            if (job == null)
            {
                throw new Exception("任务不存在");
            }
            if (req.Status == (int)JobStatus.NotRun) //停止
            {
                job.Stop(_scheduler);
            }
            else //启动
            {
                job.Start(_scheduler);
            }
            job.Status = req.Status;
            job.UpdateTime = DateTime.Now;
            job.UpdateUserId = _auth.AccountId;
            job.UpdateUserName = _auth.AccountName;
            Update(job);
        }
        /// <summary>
        /// 记录任务运行结果
        /// </summary>
        /// <param name="jobId"></param>
        public void RecordRun(string jobId)
        {
            var job = Find(u => u.ID == jobId);
            if (job == null)
            {
                _sysLog.Add(new SysLog
                {
                    TypeName = "定时任务",
                    TypeId = "AUTOJOB",
                    Content = $"未能找到定时任务：{jobId}"
                });
                return;
            }

            job.RunCount++;
            job.LastRunTime = DateTime.Now;
            Update(job);

            _sysLog.Add(new SysLog
            {
                CreateName = "Quartz",
                CreateId = "Quartz",
                TypeName = "定时任务",
                TypeId = "AUTOJOB",
                Content = $"运行了自动任务：{job.JobName}"
            });
            _logger.LogInformation($"运行了自动任务：{job.JobName}");
        }
        #endregion
    }
}